// SPDX-License-Identifier: GPL-2.0
/*
 * COW
 *
 * (C) 2024.05.01 BuddyZhang1 <buddy.zhang@aliyun.com>
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>

#define MAP_SIZE	0x1000

int main()
{
	void *mem;
	int pid;

	/* ALLOC MEMORY */
	mem = mmap(NULL, MAP_SIZE,
		   PROT_READ | PROT_WRITE,
		   MAP_ANONYMOUS | MAP_PRIVATE,
		   -1,
		   0);
	if (mem == MAP_FAILED) {
		printf("ERROR: ALLOC MEMORY FAILED.\n");
		return -1;
	}

	/* ACCESS */
	*(char *)mem = 'B';

	pid = fork();

	/* COW */
	if (pid == 0) { /* CHILD */
		/* WRITE OPS, MAPCOUNT == 2 TRIGGER #PF COPY PAGE */
		*(char *)mem = 'C';
	} else { /* FATHER */
		sleep(0.5);
		/* WRITE OPS, MAPCOUNT == 1 TRIGGER #PF REUSE PAGE */
		*(char *)mem = 'D';
	}
	
	/* ACCESS */
	printf("PID-%d: %c\n", pid, *(char *)mem);

	/* RECLAIM */
	munmap(mem, MAP_SIZE);

	return 0;
}
